4. JWT VS WEB TOKENS

Stateful vs stateless authentication

Statefull
In statefull the server keeps tracks of the users session . It can store the user session data into a database like redis uses session id stored in cookie to identify and auth user on each request

stateless
server dosent keep track of user session thus each user request much carry all the necessary information in a form of token like a JWT(JSON WEB TOKEN)
the server validates the token without storing session data

JWT(JSON WEB TOKEN )
consider you login in to a webpage you enter your username and password the server verifies your creds if correct then it creates a JWT and sends it back to you
it contains

Comparison Summary

Feature Stateful Stateless
Scalability Harder to scale, needs session sync Easier to scale, no session storage needed
Server Load Higher (sessions stored on server) Lower (no session storage)
Security Easier to manage session security Tokens can be exposed, client-side risk
Implementation Simple for traditional web apps Ideal for APIs and microservices
Token Management Easy to log out users Revoking tokens is harder
Session Handling Maintained on the server Managed on the client

1. Bcrypt

Bcrypt is a password hashing algorithm that helps keep passwords secure
As my password schema is stored in my user model.js.

bcrypt.hash - a method used to securely hash a password or string, making it unreadable, by applying a cryptographic algorithm with a salt to enhance security

.pre - middleware in Mongoose is a function that runs before a certain event (like saving or validating a document), allowing you to perform operations or modify data before it is processed.

bcrypt.compare is a method used to compare a plain text password with a hashed password to check if they match.

src/model/user model.js

//User Model.js
import bcrypt from 'bcrypt';

userSchema.pre("save", async function (next) {
    if (!this.isModified("password")) return next(); //password not modified
    try {
    //password Modified then run this 
        this.password = await bcrypt.hash(this.password, 10)
        next(); //once password is hashed it will save 
    }
    catch (error) {
        next(err);
    }
});

//use for password comparing
userSchema.methods.isPasswordCorrect = async function (password) {
    return await bcrypt.compare(password, this.password)
}

2. JWT (JSON Web Token)

JWT (JSON Web Token) is a compact, URL-safe token used to securely transmit information between two parties as a JSON object.

Example

A typical JWT token looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

This token is divided into three parts:

  1. Header (first part) - Contains metadata about the token, such as the signing algorithm used (e.g., HS256).
  2. Payload (second part) - Contains the claims or data, like user information (e.g., namesub for subject, etc.).
  3. Signature (third part) - Ensures the token hasn't been tampered with. It's generated using the header, payload, and a secret key.

When decoded, the payload might look like:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

The signature is used to verify that the sender is who it says it is and to ensure that the message wasn’t altered.

3. Refresh Token

A refresh token is a credential used to obtain a new access token when the current access token expires, without requiring the user to log in again.

Example:

  1. User logs in and receives an access token (valid for 1 hour) and a refresh token (valid for 7 days).
  2. When the access token expires, the user can send the refresh token to the server to obtain a new access token.

Implementing in OnlyTube

.env

Configuring .env

ACCESS_TOKEN_SECRET = 511Yq7tvCubJlV6cR8xRyBWOmgZL4t2uAi93D5abE9DjVFvCZ7zevTcjxr96h0el
ACCESS_TOKEN_EXPIRY = 1d 

REFRESH_TOKEN_SECRET = bww5VJzg2bTdaPZ2R8i5X0rubl4HM6wQlxuCrfU2qV6aDq0azyGhPDCcFYzeE3xI
REFRESH_TOKEN_EXPIRY = 10d

src/model/user model.js


//user model.js
//to generate Access token using JWT
userSchema.methods.generateAccessToken = function () {
    return jwt.sign({
        _id: this._id,
        email: this.email,
        username: this.username,
        fullName: this.fullName,
    },
        process.env.ACCESS_TOKEN_SECRET,
        {
            expiresIn: process.env.ACCESS_TOKEN_EXPIRY
        }
    )
};

/// Generate Refresh Tokens using JWT
userSchema.methods.generateRefreshTokens = function () {
    jwt.sign({
        _id: this.id,
    },
        process.env.REFRESH_TOKEN_SECRET,
        {
            expiresIn: process.env.REFRESH_TOKEN_EXPIRY
        }
    )
}